package com.wframe.project.jnd.extinterface.oss;

import java.io.*;
import java.net.URI;
import java.net.URLDecoder;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;

public class AliyunOssUtils {

	public List<String> getFileList(String dir){
		String prefix=dir;
		OSSClient client = new OSSClient(AliyunOssConfig.getConfig().getEndpoint(), AliyunOssConfig.getConfig().getAccessId(), AliyunOssConfig.getConfig().getAccessSecret());
		ListObjectsRequest objrequest=new ListObjectsRequest(AliyunOssConfig.getConfig().getBucket());
		if(StringUtils.isNotBlank(prefix)){
			if(!prefix.endsWith("/"))prefix+="/";
			objrequest.withPrefix(prefix);
		}
		ObjectListing objectListing = client.listObjects(objrequest);
		List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
		List<String> list=new ArrayList<String>();
		for (OSSObjectSummary s : sums)
            list.add(s.getKey());
		return list;
	}
	/**
     * 获取post 主体
     *
     * @param is         request.getInputStream()
     * @param contentLen 内容长度
     * @return post内容
     */
    public static final String getPostBody(InputStream is, int contentLen) {
        if (contentLen > 0) {
            int readLen = 0;
            int readLengthThisTime = 0;
            byte[] message = new byte[contentLen];
            try {
                while (readLen != contentLen) {
                    readLengthThisTime = is.read(message, readLen, contentLen - readLen);
                    if (readLengthThisTime == -1) {// Should not happen.
                        break;
                    }
                    readLen += readLengthThisTime;
                }
                return new String(message);
            } catch (IOException e) {
            }
        }
        return "";
    }
    
    /**
     * 校验是不是AliyunOSS服务器发来的Callback请求
     *
     * @param request         request
     * @param ossCallbackBody request主体
     * @return
     * @throws NumberFormatException
     * @throws IOException
     */
    public static final boolean verifyOSSCallbackRequest(HttpServletRequest request, String ossCallbackBody)
            throws NumberFormatException, IOException {
        boolean ret = false;
        try {

            String autorizationInput = new String(request.getHeader("Authorization"));
            String pubKeyInput = request.getHeader("x-oss-pub-key-url");
            byte[] authorization = BinaryUtil.fromBase64String(autorizationInput);
            byte[] pubKey = BinaryUtil.fromBase64String(pubKeyInput);
            String pubKeyAddr = new String(pubKey);
            if (!pubKeyAddr.startsWith("http://gosspublic.alicdn.com/") && !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/")) {
                return false;
            }
            String retString = executeGet(pubKeyAddr);
            retString = retString.replace("-----BEGIN PUBLIC KEY-----", "");
            retString = retString.replace("-----END PUBLIC KEY-----", "");
            String queryString = request.getQueryString();
            String uri = request.getRequestURI();
            String decodeUri = java.net.URLDecoder.decode(uri, "UTF-8");
            String authStr = decodeUri;
            if (queryString != null && !queryString.equals("")) {
                authStr += "?" + queryString;
            }
            authStr += "\n" + ossCallbackBody;
            ret = doCheck(authStr, authorization, retString);
        }catch (Exception e){
            return false;
        }
        return ret;
    }
    
    /**
     * 想AliyunOSS服务器发起请求，获得结果用于检查是否是服务器发起的Callback请求
     *
     * @param url AliyunOSS服务器路径
     * @return 请求结果
     */
    public static final String executeGet(String url) {
        BufferedReader in = null;

        String content = null;
        try {
            // 定义HttpClient
            @SuppressWarnings("resource")
            DefaultHttpClient client = new DefaultHttpClient();
            // 实例化HTTP方法
            HttpGet request = new HttpGet();
            request.setURI(new URI(url));
            HttpResponse response = client.execute(request);

            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
            }
            in.close();
            content = sb.toString();
        } catch (Exception e) {
        } finally {
            if (in != null) {
                try {
                    in.close();// 最后要关闭BufferedReader
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return content;
        }
    }
    
    /**
     * 检查公钥和数字签名是否正确
     *
     * @param content   需要检查的内容
     * @param sign      数字签名
     * @param publicKey 公钥
     * @return
     */
    public static final boolean doCheck(String content, byte[] sign, String publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] encodedKey = BinaryUtil.fromBase64String(publicKey);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            java.security.Signature signature = java.security.Signature.getInstance("MD5withRSA");
            signature.initVerify(pubKey);
            signature.update(content.getBytes());
            boolean bverify = signature.verify(sign);
            return bverify;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
    
    /**
     * 返回给Aliyun服务器
     *
     * @param request
     * @param response
     * @param results  需要返回的结果
     * @param status   处理状态
     * @throws IOException
     */
    public static void response(HttpServletRequest request, HttpServletResponse response, String results, int status) throws IOException {
        String callbackFunName = request.getParameter("callback");
        response.addHeader("Content-Length", String.valueOf(results.length()));
        if (callbackFunName == null || callbackFunName.equalsIgnoreCase(""))
            response.getWriter().println(results);
        else
            response.getWriter().println(callbackFunName + "( " + results + " )");
        response.setStatus(status);
        response.flushBuffer();
    }

	public static Map<String, String> URLParamToMap(String paramcontent) throws UnsupportedEncodingException
    {
	    Map<String, String> mapRequest = new HashMap<String, String>();
	    if(StringUtils.isBlank(paramcontent))return mapRequest;
	    String[] arrSplit=paramcontent.split("[&]");
	    for(String strSplit:arrSplit)
	    {
	          String[] arrSplitEqual=null;         
	          arrSplitEqual= strSplit.split("[=]");
	          if(arrSplitEqual.length>1)
	          {
	              mapRequest.put(arrSplitEqual[0], URLDecoder.decode(arrSplitEqual[1], "utf-8"));
	          }
	          else
	          {
	              if(arrSplitEqual[0]!="")
	              {
	              mapRequest.put(arrSplitEqual[0], "");       
	              }
	          }
	    }   
	    	return mapRequest;   
	 }
	
}
